Import yimWork

Class yimTileMap
	Field pos:yimVec2D
	Field mapSize:yimVec2D
	
	Field numTiles:yimVec2D
	Field tileSize:yimVec2D
	Field tileW:Int
	Field tileH:Int
	
	Field layer:yimSpriteLayer
	
	Field tileList:List<yimTile> = New List<yimTile>()
	Field sourceTiles:List<yimTile> = New List<yimTile>()
	Field curSourceTile:yimTile = Null
	
	Field collGroup:yimCollGroup
	
	Field doDrawGrid:Bool = False
	
	Field hiliteList:List<yimVec2D> = New List<yimVec2D>()
	
	Method New(_layer:yimSpriteLayer, tileWidth:Float, tileHeight:Float, numTilesX:Int, numTilesY:Int, xPos:Float=0.0, yPos:Float=0.0)
		layer = _layer
		
		pos = New yimVec2D(xPos, yPos)
		mapSize = New yimVec2D(tileWidth*numTilesX, tileHeight*numTilesY)
		
		numTiles = New yimVec2D(numTilesX, numTilesY)
		tileW = tileWidth
		tileH = tileHeight
		
		tileSize = New yimVec2D(tileWidth, tileHeight)
		
		collGroup = layer.parent.eng.CreateCollGroup("Ummmmmm", False)
	End
	
	Method AddSourceSprite(name:String, sprFile:String, frameWidth:Int, frameHeight:Int, numFrames:Int=1)
		Local tSpr:yimSprite = layer.parent.eng.LoadSpriteSheet(sprFile, frameWidth, frameHeight, numFrames)
		tSpr.SetVisible(False)
		For Local i:= 0 Until numFrames
			sourceTiles.AddLast(New yimTile(0, 0, tSpr, i, name))
		Next
	End
	
	Method NextSourceTile:yimTile(afterTile:yimTile=Null)
		If afterTile
			curSourceTile = afterTile
		EndIf
		
		If curSourceTile
			If curSourceTile = sourceTiles.Last()
				curSourceTile = sourceTiles.First()
				Return curSourceTile
			EndIf
			
			Local retTile:Bool = False
			
			For Local t:= EachIn sourceTiles
				If retTile
					curSourceTile = t
					Return curSourceTile
				EndIf
				If curSourceTile = t
					retTile = True
				EndIf
			Next
		EndIf
		curSourceTile = sourceTiles.First()
		Return curSourceTile
	End
	
	Method PrevSourceTile:yimTile(beforeTile:yimTile=Null)
		If beforeTile
			curSourceTile = beforeTile
		EndIf
		
		If curSourceTile
			If curSourceTile = sourceTiles.First()
				curSourceTile = sourceTiles.Last()
				Return curSourceTile
			EndIf
			
			Local retTile:yimTile = Null
			
			For Local t:= EachIn sourceTiles
				If curSourceTile = t
					curSourceTile = retTile
					Return curSourceTile
				EndIf
				retTile = t
			Next
		EndIf
		
		curSourceTile = sourceTiles.First()
		Return curSourceTile
	End
	
	Method AddTile(srcName:String, tileX:Int, tileY:Int, frame:Int=0, coll:Bool=False)
		If Not GetTile(tileX, tileY)
			Local srcSpr:yimSprite = GetSourceSprite(srcName)
			Local curLayer:yimSpriteLayer = layer.parent.curLayer
			layer.parent.curLayer = layer
			
			Local tSpr:yimSprite = layer.parent.eng.CloneSprite(srcSpr)
			
			tileList.AddLast(New yimTile(tileX, tileY, tSpr, frame, srcName))
			
			If coll
				'collGroup.AddBody(tSpr, New yimCollBodyTypeRect(tSpr.Width(), tSpr.Height()))
			EndIf
			
			tSpr.SetPosition(pos.x + tileX*tileSize.x + tileSize.x/2.0, pos.y + tileY*tileSize.y + tileSize.y/2)
			If frame > 0
				tSpr.SetFrame(frame)
			EndIf
			layer.parent.curLayer = curLayer
		EndIf
	End
		
	Method GetSourceSprite:yimSprite(name:String)
		For Local t:= EachIn sourceTiles
			If t.id = name
				Return t.spr
			EndIf
		Next
	End
	
	Method RemoveTile(tileX:Int, tileY:Int)
		Local tTile:yimTile = GetTile(tileX, tileY)
		If tTile
			layer.parent.eng.RemoveSprite(tTile.spr)
			tileList.Remove(tTile)
		EndIf
	End
	
	Method AddHilite(tileX:Float, tileY:Float)
		hiliteList.AddLast(New yimVec2D(tileX, tileY))
	End
	
	Method PointToTile:yimVec2D(x:Float, y:Float)
		If x > pos.x And x < pos.x+mapSize.x And y > pos.y And y < pos.y + mapSize.y
			
			Local tileX:Int = Int(x-pos.x) / tileW
			Local tileY:Int = Int(y-pos.y) / tileH
			
			Return New yimVec2D(tileX, tileY)
		EndIf
		
		Return Null
	End
	
	Method GetTile:yimTile(x:Int, y:Int)
		For Local tTile:yimTile = EachIn tileList
			If tTile.x = x And tTile.y = y
				Return tTile
			EndIf
		Next
		
		Return Null
	End
	
	Method ClearHilites()
		hiliteList.Clear()
	End
	
	Method DrawGrid()
		yim_SaveAlpha()
		yim_SaveColor()
		
		SetColor(255, 255, 255)
		SetAlpha(0.3)
		
		Local eng:yimEngine = layer.parent.eng
		
		For Local x:Int = 0 To numTiles.x
			DrawLine(pos.x + x*tileSize.x, pos.y, pos.x + x*tileSize.x, pos.y - mapSize.y)
		Next
		
		For Local y:Int = 0 To numTiles.y
			DrawLine(pos.x, pos.y - y*tileSize.y, pos.x + mapSize.x, pos.y - y*tileSize.y)
		Next
		
		SetAlpha(1.0)
		SetColor(255, 0, 0)
		
		For Local tHi:= EachIn hiliteList
			DrawUnfilledRect(pos.x + tHi.x*tileSize.x, pos.y - (tHi.y+1)*tileSize.y, tileSize.x, tileSize.y)
		Next
				
		yim_RestoreAlpha()
		yim_RestoreColor()
	End
	
	Method SaveToFile(file:String)
		Local str:String = tileW+","+tileH+","+Int(size.x)+","+Int(size.y)+","+rect.x+","+rect.y+"|"
		
		For Local tTile:= EachIn tileList
			str += tTile.ToString()+"|"
		Next
		
		yimSaveString(file, str)
	End
	
	Method ClearMap()
		For Local tTile:= EachIn tileList
			layer.parent.eng.RemoveSprite(tTile.spr)
		Next
		tileList.Clear()
	End
	
End

Class yimTile
	Field spr:yimSprite
	Field frame:Int
	Field x:Int
	Field y:Int
	Field id:String
	
	Method New(tileX:Int, tileY:Int, _spr:yimSprite, _frame:Int, _id:String)
		spr = _spr
		x = tileX
		y = tileY
		frame = _frame
		id = _id.Replace("|", "(PIPE)").Replace(",","(COMMA)")
	End
	
	Method ToString:String()
		Local str:String = id+","+frame+","+x+","+y
		Return str
	End
End